use serde::{Deserialize, Serialize};
use std::net::SocketAddr;

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ClientConfig {
    pub server: String,
    pub auth: String,

    #[serde(default)]
    pub obfs: ObfsConfig,

    #[serde(default)]
    pub tls: TlsConfig,

    #[serde(default)]
    pub bandwidth: BandwidthConfig,

    pub socks5: Option<Socks5Config>,
    pub http: Option<HttpConfig>,
}

#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct ObfsConfig {
    #[serde(rename = "type")]
    pub obfs_type: Option<String>,
    pub salamander: Option<SalamanderConfig>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SalamanderConfig {
    pub password: String,
}

#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct TlsConfig {
    pub sni: Option<String>,
    #[serde(default)]
    pub insecure: bool,
}

#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct BandwidthConfig {
    pub up: String,
    pub down: String,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Socks5Config {
    pub listen: SocketAddr,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct HttpConfig {
    pub listen: SocketAddr,
}

impl ClientConfig {
    pub fn from_file(path: &str) -> anyhow::Result<Self> {
        let content = std::fs::read_to_string(path)?;
        let config = serde_yaml::from_str(&content)?;
        Ok(config)
    }
}
